ARD2  RC2
Airbag Reference Demonstrator using MPC5604P
Central_Accel_AL.c
Go to the documentation of this file.
00001 
00019 #include "derivative.h" /* Contains type declarations */
00020 #include "compile_options.h"
00021 #include "Central_Accel_AL.h"
00022 #include "MMA68xx.h"
00023 #include "MMA68xx_Diag.h"
00024 #include "HAL.h"
00025 #include "MailScheduler.h"
00026 #include "DSPI.h"
00027 #include "Utils.h"
00028 #include <limits.h> /* To set limits */
00029 /*
00030  ******************************************************************************
00031  * Constants
00032  ******************************************************************************
00033  */
00038 const uint16_t cau16MMA6800ResetSettings[] =
00039 {
00040   /* Sequence below is needed to perform a soft-reset */
00041   (MMA6800_DEVCTL | (MMA6800_WRITE_REGISTER << CHAR_BIT) | CLEAR),
00042   (MMA6800_DEVCTL | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0xC0u),
00043   (MMA6800_DEVCTL | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x40u),
00044   /* According to the spec, DEVSTAT should be read twice afterwards  */
00045   (MMA6800_DEVSTAT | (MMA6800_READ_REGISTER << CHAR_BIT) | CLEAR),
00046   (MMA6800_DEVSTAT | (MMA6800_READ_REGISTER << CHAR_BIT) | CLEAR)};
00047 
00048 const uint16_t cau16MMA6800InitSettings[] =
00049 {
00050   /* Configure X-axis for 150Hz, 4-pole LPF */
00051   (MMA6800_DEVCFG_X | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x09u),
00052   /* Configure Y-axis for 200Hz, 4-pole LPF */
00053   (MMA6800_DEVCFG_Y | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x0Au),
00054   /* Configure X-axis for ARM pulse stretch of 262msec  */
00055   (MMA6800_ARMCFGX | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x33u), /*PB */
00056   /* Configure Y-axis for ARM pulse stretch of 262msec  */
00057   (MMA6800_ARMCFGY | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x33u), /*PB */
00058   /* Configure X-axis Arming Threshold - Positive  */
00059   (MMA6800_ARMT_XP | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u),
00060   /* Configure Y-axis Arming Threshold - Positive  */
00061   (MMA6800_ARMT_YP | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u),
00062   /* Configure X-axis Arming Threshold - Negative  */
00063   (MMA6800_ARMT_XN | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u),
00064   /* Configure Y-axis Arming Threshold - Negative  */
00065   (MMA6800_ARMT_YN | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x05u),
00066   /* Configure device for PCM output, signed data, Offset monitor disabled */
00067   /* Also, don't fix data from further changes because of CA test */
00068   (MMA6800_DEVCFG | (MMA6800_WRITE_REGISTER << CHAR_BIT) | 0x15u)};
00069 
00070 const uint8_t cu8SizeofMMA6800ResetSettings = N_ELEMENTS(cau16MMA6800ResetSettings);
00071 const uint8_t cu8SizeofMMA6800InitSettings = N_ELEMENTS(cau16MMA6800InitSettings);
00072 /*
00073  ******************************************************************************
00074  * Globals
00075  ******************************************************************************
00076  */
00077 /*
00078  ******************************************************************************
00079  * vfnCAPreSchedulerInit
00080  ******************************************************************************
00081  */
00082 void vfnCAPreSchedulerInit(void)
00083 {
00084   /* Void */
00085   return;
00086 }
00087 /*
00088  ******************************************************************************
00089  * u8fnCAInit
00090  ******************************************************************************
00091  */
00092 uint32_t u32fnCAInit(void)
00093 {
00094   uint32_t u32Status;
00095   uint8_t u8Counter;
00096   
00097   u32Status = CLEAR;
00098   u8Counter = CLEAR;
00099   
00100   u32Status = (*u8pfnMMA6800BatchOp[MMA6800_TRANSFER_MODE_IS_SCHEDULED])
00101             (MAIN_ACCELERO_SPI_CONFIG,(uint16_t*)cau16MMA6800ResetSettings,
00102             (uint16_t*)gau8MMA6800GlobalResult,
00103             (uint8_t)N_ELEMENTS(cau16MMA6800ResetSettings));  
00104   
00105   DELAY_MSEC(1u);  
00106   
00107   u32Status = (*u8pfnMMA6800BatchOp[MMA6800_TRANSFER_MODE_IS_SCHEDULED])
00108             (MAIN_ACCELERO_SPI_CONFIG,(uint16_t*)cau16MMA6800InitSettings,
00109             (uint16_t*)gau8MMA6800GlobalResult,
00110             (uint8_t)N_ELEMENTS(cau16MMA6800InitSettings)); 
00111   
00112   DELAY_MSEC(1u);  
00113   
00114   do
00115   {
00116     u32Status = u32fnCAInitSelfTest();
00117     u8Counter++;
00118   }while((u32Status != CLEAR) && (u8Counter < 5));
00119     
00120   u32Status |= u8fnMMA6800WriteRegister(MAIN_ACCELERO_SPI_CONFIG,
00121                                        MMA6800_TRANSFER_MODE_IS_SCHEDULED,
00122                                        MMA6800_DEVCFG, 0x35, 
00123                                        (uint16_t*) &gau8MMA6800GlobalResult);
00124 
00125   return (u32Status);
00126 }
00127 /*
00128  ******************************************************************************
00129  * u32fnCAScheduleAccelXY
00130  ******************************************************************************
00131  */
00132 uint32_t u32fnCAScheduleAccelXY(uint16_t* pu16RawDestination)
00133 {
00134   uint8_t u8Status;
00135   uint32_t u32Status;
00136   
00137   u32Status = CLEAR;
00138   
00139   u8Status = u8fnMMA6800ReadAccel(MAIN_ACCELERO_SPI_CONFIG, 
00140                                   MMA6800_TRANSFER_MODE_IS_SCHEDULED, 
00141                                   (MMA6800_READ_X |MMA6800_READ_Y), 
00142                                   CURRENT_ACCEL_MODE, pu16RawDestination, 
00143                                   CURRENT_CA);
00144   if(CLEAR < u8Status)
00145   {
00146     u32Status = STATUS_CA_FAILED;
00147   }
00148   else
00149   {
00150     /* Nothing to do */
00151   }
00152 
00153   return(u32Status);
00154 }
00155 /*
00156  ******************************************************************************
00157  * u32fnCAScheduleAccelXY
00158  ******************************************************************************
00159  */
00160 uint32_t u32fnCAScheduleAccelX(uint16_t* pu16RawDestination)
00161 {
00162   uint8_t u8Status;
00163   uint32_t u32Status;
00164   
00165   u32Status = CLEAR;
00166   
00167   u8Status = u8fnMMA6800ReadAccel(MAIN_ACCELERO_SPI_CONFIG, 
00168                                   MMA6800_TRANSFER_MODE_IS_SCHEDULED, 
00169                                   MMA6800_READ_X,
00170                                   CURRENT_ACCEL_MODE, pu16RawDestination,
00171                                   CURRENT_CA);
00172   if(CLEAR < u8Status)
00173   {
00174     u32Status = STATUS_CA_FAILED;
00175   }
00176   else
00177   {
00178     /* Nothing to do */
00179   }
00180 
00181   return(u32Status);
00182 }
00183 /*
00184  ******************************************************************************
00185  * u32fnCAScheduleAccelXY
00186  ******************************************************************************
00187  */
00188 uint32_t u32fnCAScheduleAccelY(uint16_t* pu16RawDestination)
00189 {
00190   uint8_t u8Status;
00191   uint32_t u32Status;
00192   
00193   u32Status = CLEAR;
00194   
00195   u8Status = u8fnMMA6800ReadAccel(MAIN_ACCELERO_SPI_CONFIG, 
00196                                   MMA6800_TRANSFER_MODE_IS_SCHEDULED, 
00197                                   (MMA6800_READ_Y),
00198                                   CURRENT_ACCEL_MODE, pu16RawDestination,
00199                                   CURRENT_CA);
00200   if(CLEAR < u8Status)
00201   {
00202     u32Status = STATUS_CA_FAILED;
00203   }
00204   else
00205   {
00206     /* Nothing to do */
00207   }
00208 
00209   return(u32Status);
00210 }
00211 
00212 /*
00213  ******************************************************************************
00214  * u32fnCAExtractXY
00215  ******************************************************************************
00216  */
00217 uint32_t u32fnCAExtractXY(uint16_t* pu16RawSource, uint16_t* pu16FilteredXY)
00218 {
00219   /* Local variables */
00220   uint8_t u8Status;
00221   uint32_t u32Status;
00222   uint16_t au16TempResults[RAW_MMA_ACCEL_ARRAY_SIZE];
00223   
00224   u32Status = CLEAR;
00225   u8Status = u8fnMMA6800ExtractAccelResponse(pu16RawSource,
00226                                              (uint16_t*)au16TempResults,
00227                                              RAW_MMA_ACCEL_ARRAY_SIZE,
00228                                              CURRENT_CA);
00229   /* Because of how Mesquite/Sycamore works, we're only interested in the  */
00230   /* second and third items of this response. We will forget the first one */
00231   *(pu16FilteredXY++) = au16TempResults[1u];
00232   *(pu16FilteredXY) = au16TempResults[2u];
00233   
00234   if(CLEAR != u8Status)
00235   {
00236     u32Status = STATUS_CA_FAILED;
00237   }
00238   else
00239   {
00240     /* Get out */
00241   }
00242   
00243   return (u32Status);
00244 }
00245 /*
00246  ******************************************************************************
00247  * u32fnCAExtractX
00248  ******************************************************************************
00249  */
00250 uint32_t u32fnCAExtractX(uint16_t* pu16RawSource, uint16_t* pu16FilteredX)
00251 {
00252   /* Local variables */
00253   uint8_t u8Status;
00254   uint32_t u32Status;
00255   uint16_t au16TempResults[RAW_MMA_ACCEL_ARRAY_SIZE - 1u];
00256   
00257   u32Status = CLEAR;
00258   u8Status = u8fnMMA6800ExtractAccelResponse(pu16RawSource,
00259                                              (uint16_t*)au16TempResults,
00260                                              RAW_MMA_ACCEL_ARRAY_SIZE - 1u,
00261                                              CURRENT_CA);
00262   /* Because of how Mesquite/Sycamore works, we're only interested in the  */
00263   /* second item of this response. We will forget the first one            */
00264   *pu16FilteredX = au16TempResults[1u];
00265   
00266   if(CLEAR != u8Status)
00267   {
00268     u32Status = STATUS_CA_FAILED;
00269   }
00270   else
00271   {
00272     /* Get out */
00273   }
00274   
00275   return (u32Status);
00276 }
00277 /*
00278  ******************************************************************************
00279  * u32fnCAInitSelfTest
00280  ******************************************************************************
00281  */
00282 uint32_t u32fnCAInitSelfTest(void)
00283 {
00284   /* Declare local variables */
00285   uint32_t u32Status;
00286 
00287   /* Init local variables */
00288   u32Status = CLEAR;
00289 
00290   /* Read Part Number Register to access to sensitivity */
00291   u32Status = u8fnMMA6800ReadRegister(MAIN_ACCELERO_SPI_CONFIG,
00292                                       MMA6800_TRANSFER_MODE_IS_SCHEDULED,
00293                                       MMA6800_PN, (uint16_t*) &gau8MMA6800GlobalResult);
00294   DELAY_MSEC(550u);
00295 
00296   /**************************** Self Tests for both X and Y axis ***************************/
00297   u32Status |= u32fnCASelfTest((uint8_t) MMA6800_READ_X);
00298   u32Status |= u32fnCASelfTest((uint8_t) MMA6800_READ_Y);
00299 
00300   return(u32Status);
00301 }
00302 /*
00303  ******************************************************************************
00304  * u32fnCAInitSelfTest
00305  ******************************************************************************
00306  */
00307 uint32_t u32fnCASelfTest(const uint8_t cu8Axis)
00308 {
00309   /* Declare local variables */
00310   uint32_t u32Status;
00311   uint32_t au32FilteredSum[6];
00312   uint32_t au32StatusErrCode[6];
00313   uint16_t au16Raw[3];
00314   uint16_t au16RawCross[3];
00315   uint16_t au16OC[3];
00316   uint16_t au16OCCross[3];
00317   uint8_t u8Counter;
00318 
00319   /* Init local variables */
00320   u32Status = CLEAR;
00321   
00322   /*Assign correct error code and correct settings for PowerOnSelfTest function*/
00323   /*according to axis required*/
00324   if(MMA6800_READ_X == cu8Axis)
00325   {
00326     for(u8Counter = CLEAR; u8Counter < cu8SizeofTestAmount; u8Counter++)
00327     {
00328       au32StatusErrCode[u8Counter] = cau32MMA6800ErrorCodeX[u8Counter];
00329       if(u8Counter < cu8SizeofTestSettings)
00330       {
00331         au16Raw[u8Counter] = cau16MMA6800TestSettingsRawSelfX[u8Counter];
00332         au16RawCross[u8Counter] = cau16MMA6800TestSettingsRawSelfY[u8Counter];
00333         au16OC[u8Counter] = cau16MMA6800TestSettingsOCSelfX[u8Counter];
00334         au16OCCross[u8Counter] = cau16MMA6800TestSettingsOCSelfY[u8Counter];        
00335       }
00336     }
00337   }
00338   else
00339   {
00340     for(u8Counter = CLEAR; u8Counter < cu8SizeofTestAmount; u8Counter++)
00341     {
00342       au32StatusErrCode[u8Counter] = cau32MMA6800ErrorCodeY[u8Counter];
00343       if(u8Counter < cu8SizeofTestSettings)
00344       {
00345         au16Raw[u8Counter] = cau16MMA6800TestSettingsRawSelfY[u8Counter];
00346         au16RawCross[u8Counter] = cau16MMA6800TestSettingsRawSelfX[u8Counter];
00347         au16OC[u8Counter] = cau16MMA6800TestSettingsOCSelfY[u8Counter];
00348         au16OCCross[u8Counter] = cau16MMA6800TestSettingsOCSelfX[u8Counter];        
00349       }
00350     }
00351   }
00352 
00353   /**************************** Pre Self Test, Raw data *************************************/
00354   u32Status |= u32fnMMA6800PreSelfTest((uint32_t*) &au32FilteredSum[0],
00355                                        (uint16_t*) cau16MMA6800TestSettingsRaw,
00356                                        (uint8_t) cu8SizeofTestSettings,
00357                                        (uint8_t) RAW_ACCEL_MODE,
00358                                        (uint8_t) cu8Axis,
00359                                        (uint16_t) CA_TEST_RAW_LIMIT_LO,
00360                                        (uint16_t) CA_TEST_RAW_LIMIT_HI,
00361                                        (uint32_t) au32StatusErrCode[0],
00362                                        (uint8_t) CURRENT_CA);
00363 
00364   /******************************* Power On Self Test, Raw data ****************************/   
00365   u32Status |= u32fnMMA6800PowerOnSelfTest((uint32_t*) &au32FilteredSum[1],
00366                                            (uint16_t*) au16Raw,
00367                                            (uint16_t*) au16RawCross,
00368                                            (uint8_t) cu8SizeofTestSettings,
00369                                            (uint8_t) RAW_ACCEL_MODE,
00370                                            (uint8_t) cu8Axis,
00371                                            (uint32_t) au32StatusErrCode[1],
00372                                            (uint8_t) CURRENT_CA);
00373 
00374   /*********************************** Post Self Test, Raw data  ****************************/
00375   u32Status |= u32fnMMA6800PostSelfTest((uint32_t*) &au32FilteredSum[2],
00376                                         (uint16_t*) cau16MMA6800TestSettingsRaw,
00377                                         (uint8_t) cu8SizeofTestSettings,
00378                                         (uint8_t) RAW_ACCEL_MODE,
00379                                         (uint8_t) cu8Axis,
00380                                         (uint32_t) au32StatusErrCode[2],
00381                                         (uint8_t) CURRENT_CA);
00382 
00383   /**************************** Pre Self Test, OC data **************************************/
00384   u32Status |= u32fnMMA6800PreSelfTest((uint32_t*) &au32FilteredSum[3],
00385                                        (uint16_t*) cau16MMA6800TestSettingsOC,
00386                                        (uint8_t) cu8SizeofTestSettings,
00387                                        (uint8_t) OC_ACCEL_MODE,
00388                                        (uint8_t) cu8Axis,
00389                                        (uint16_t) CA_TEST_OC_LIMIT_LO,
00390                                        (uint16_t) CA_TEST_OC_LIMIT_HI,
00391                                        (uint32_t) au32StatusErrCode[3],
00392                                        (uint8_t) CURRENT_CA);
00393 
00394   /********************************* Power On Self Test, OC data ****************************/
00395   u32Status |= u32fnMMA6800PowerOnSelfTest((uint32_t*) &au32FilteredSum[4],
00396                                            (uint16_t*) au16OC,
00397                                            (uint16_t*) au16OCCross,
00398                                            (uint8_t) cu8SizeofTestSettings,
00399                                            (uint8_t) OC_ACCEL_MODE,
00400                                            (uint8_t) cu8Axis,
00401                                            (uint32_t) au32StatusErrCode[4],
00402                                            (uint8_t) CURRENT_CA);
00403 
00404   /*********************************** Post Self Test, OC data *******************************/
00405   u32Status |= u32fnMMA6800PostSelfTest((uint32_t*) &au32FilteredSum[5],
00406                                         (uint16_t*) cau16MMA6800TestSettingsOC,
00407                                         (uint8_t) cu8SizeofTestSettings,
00408                                         (uint8_t) OC_ACCEL_MODE,
00409                                         (uint8_t) cu8Axis,
00410                                         (uint32_t) au32StatusErrCode[5],
00411                                         (uint8_t) CURRENT_CA);
00412 
00413   return(u32Status);
00414 }
00415 /*
00416  ******************************************************************************
00417  *
00418  *  End of file.
00419  *
00420  ******************************************************************************
00421  */